package com.essence.grabiec104.grab.strategy;

import com.essence.common.model.EnumTypeAdapter;
import com.essence.grabiec104.grab.model.AlarmRecord;
import com.essence.grabiec104.grab.model.AlarmRule;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.zeromq.ZMQ;

import java.util.List;

/**
 * 告警策略抽象类
 */
@Slf4j
public abstract class AbstractSocketAlarmStrategy {
    protected AbstractSocketAlarmStrategy next;
    protected ZMQ.Socket workerSocket;
    private Gson gson;

    public AbstractSocketAlarmStrategy() {
        gson = new GsonBuilder()
                .registerTypeAdapterFactory(new TypeAdapterFactory() {
                    @Override
                    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
                        Class<? super T> rawType = type.getRawType();
                        if (!Enum.class.isAssignableFrom(rawType)) {
                            return null;
                        }
                        TypeAdapter<T> adapter = new EnumTypeAdapter();
                        return adapter;
                    }
                })
                .create();
    }

    public void setNext(AbstractSocketAlarmStrategy next) {
        this.next = next;
    }

    public void setWorkerSocket(ZMQ.Socket workerSocket) {
        this.workerSocket = workerSocket;
    }

    public void strategyOperate(List<AlarmRule> rules) {
        doHandle(rules);
        if (next != null) {
            next.setWorkerSocket(workerSocket);
            next.strategyOperate(rules);
        }
    }

    /**
     * 获取策略名称
     * @return 策略类名
     */
    protected String getStrategyName() {
        return this.getClass().getSimpleName();
    }

    protected abstract boolean doHandle(List<AlarmRule> rules);

    protected void publish(String topic, List<AlarmRecord> records) {
        if (workerSocket != null) {
            workerSocket.sendMore(topic);
            String response = gson.toJson(records);
            workerSocket.send(response);
        } else {
            throw new UnsupportedOperationException("未设置PAIR套接字");
        }
    }
}
